package com.ww.java8.fp.stream.inaction.ch05;

import java.util.Arrays;
import java.util.function.IntSupplier;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * 参考链接
 * https://gitee.com/jack-GCQ/modern-java-in-action-master/blob/master/src/main/java/modernjavainaction/chap05/Filtering.java
 * @author wanggw
 * 2023年11月8日 下午3:58:30
 */
public class BuildingStreams {

	@SuppressWarnings("unused")
	public static void main(String[] args) {
		/**
		 * Stream.of
		 * 使用数组作为参数，创建Stream，内部使用Arrays.stream实现
		 */
		Stream<String> stream = Stream.of("Java 8", "Lambdas", "In", "Action");
		stream.map(String::toUpperCase).forEach(System.out::println);		
		System.out.println("-----------");
		
		/**
		 * Stream.empty
		 */
		Stream<String> empyStream = Stream.empty();		
		System.out.println("-----------");
		
		/**
		 * Arrays.stream
		 */
		int[] numbers = { 2, 3, 5, 7, 11, 13 };
		System.out.println(Arrays.stream(numbers).sum());		
		System.out.println("-----------");
		
		/**
		 * 由函数生成流：创建无限流
         * Stream API提供了两个静态方法来从函数生成流：Stream.iterate和Stream.generate，这两个操作可以创建所谓的无限流：
         * 不像从固定集合创建的流那样有固定大小的流。由iterate和generate产生的流会用给定的函数按需创建值，因此可以无穷无尽的计算下去
		 */
		
		/**
		 * Stream.iterate
		 */
		Stream.iterate(0, n -> n + 2)
		.limit(10)
		.forEach(System.out::println);
		// 斐波那契数列
		Stream.iterate(new int[] { 0, 1 }, t -> new int[] { t[1], t[0] + t[1] })
		.limit(10)
		.map(t -> t[0])
		.forEach(System.out::println);
		System.out.println("-----------");
		
		/**
		 * Stream.generate
		 * 生成随机数
		 */
		Stream.generate(Math::random)
		.limit(10)
		.forEach(System.out::println);
		System.out.println("-----------");
		
		IntStream.generate(() -> 1)
		.limit(5)
		.forEach(System.out::println);
		
		IntStream.generate(new IntSupplier() {
			@Override
			public int getAsInt() {
				return 2;
			};
		})
		.limit(5).forEach(System.out::println);;
		
		/**
		 * 另一种方式生成斐波那契数列
		 */
		IntSupplier fib = new IntSupplier() {
			private int previous = 0;
			private int current = 1;
			
			@Override
			public int getAsInt() {
				int nextValue = previous + current;
				previous = current;
				current = nextValue;
				return previous;
			};
		};
		IntStream.generate(fib)
		.limit(10)
		.forEach(System.out::println);
	}
}
